package tool

import (
	"crypto"
	"crypto/hmac"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/hex"
	"encoding/pem"
	"fmt"
	"sort"
	"strings"
)

func Sign(data map[string]interface{}, key string) string {
	var sortKeys []string
	for key := range data {
		sortKeys = append(sortKeys, key)
	}
	sort.Strings(sortKeys) // 对 key 进行排序

	// 2. 按照 key1=val1&key2=val2&key3=val3....&key=md5秘钥生成加密字符串
	var sb strings.Builder
	for i, k := range sortKeys {
		sb.WriteString(fmt.Sprintf("%s=%v", k, data[k]))
		if i < len(sortKeys)-1 {
			sb.WriteString("&")
		}
	}
	str := sb.String()
	// 假设要进行加密的原始消息和密钥
	// 使用HMAC-SHA256进行加密
	hash := hmac.New(sha256.New, []byte(key))
	hash.Write([]byte(str))
	encryptedMessage := hex.EncodeToString(hash.Sum(nil))

	fmt.Printf("加密后的消息: %s\n", encryptedMessage)
	return encryptedMessage
}

func verifySign(encryptedMessage, message, key string) bool {
	// 假设收到加密后的消息和原始消息，进行验签
	receivedMessage := encryptedMessage // 假设接收到加密后的消息
	originalMessage := []byte(message)
	// 重新计算HMAC并比较
	recomputedHash := hmac.New(sha256.New, []byte(key))
	recomputedHash.Write(originalMessage)
	expectedMAC := recomputedHash.Sum(nil)
	receivedMAC, err := hex.DecodeString(receivedMessage)
	if err != nil {
		fmt.Println("解码错误:", err)
		return false
	}
	// 比较接收到的MAC和重新计算的MAC
	if hmac.Equal(receivedMAC, expectedMAC) {
		return true
	} else {
		return false
	}
}

// 使用私钥对数据进行签名
func SignData(data, privateKey string) (string, error) {
	privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" + privateKey + "\n-----END RSA PRIVATE KEY-----\n"
	block, _ := pem.Decode([]byte(privateKey))
	if block == nil {
		return "", fmt.Errorf("failed to parse private key")
	}

	parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return "", err
	}
	key := parsedKey.(*rsa.PrivateKey)
	hashed := sha256.Sum256([]byte(data))
	signature, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.Hash(0), hashed[:])
	if err != nil {
		return "", err
	}

	return base64.StdEncoding.EncodeToString(signature), nil
}
